<?php
/**
 * Mapper for tusers
 * 
 * @author Martin Grossmann <snake.aas@gmail.com>
 * @version 1.0
 * @package Mappers
 *
 * @property-read int $idUser Unique user ID
 * @property string $UserName Username is used to login into system. 30 chars max
 * @property string $Password Password is used to login into system. 40 chars max
 * @property string $FirstName First Name of user. Can be null. 30 chars max
 * @property string $LastName Surname of user. Can be null. 30 chars max
 * @property-read string $FullName First and Last name of user
 * @property string $Gender Users gender
 * @property string $EMail E-mail address. 30 chars max
 * @property string $ICQ ICQ number. Can be null. 10 chars max
 * @property string $Jabber Jabber address. Can be null. 30 chars max
 * @property string $WebPage Users web page, Can be null. 60 chars max
 * @property string $AvatarUNC Path to image. Can be null. 65535 chars max
 * @property int $AvatarWidth Image width. Can be null
 * @property int $AvatarHeight Image height. Can be null
 * @property MimeType $AvatarMimeType Mimetype image. Can be null. 50 chars max
 * @property string $AvatarMimeTypeName Name of mimetype image. Can be null. 50 chars max
 * @property Language $Language User's prefered language
 * @property string $LanguageName Name of user's prefered language. 10 chars max
 * @property Style $Style User's prefered style
 * @property string $StyleName Name of user's prefered style. 30 chars max
 * @property boolean $isActive If user account is enabled
 * @property boolean $isRecovery If user account is in recovery process
 * @property DateTime $LastAction 
 * @property-read DateTime $RegistrationDate
 * @property string $Token
 * @property string $Details
 * @property-read \Doctrine\Common\Collections\ArrayCollection $Albums Collection of user's albums
 * @property-read \Doctrine\Common\Collections\ArrayCollection $Comments Collection of user's comments
 * @property-read \Doctrine\Common\Collections\ArrayCollection $Ratings Collection of user's ratings
 * @property-read \Doctrine\Common\Collections\ArrayCollection $Notitfications Collection of user's notifications
 * @property-read \Doctrine\Common\Collections\ArrayCollection $AccessibleAlbums Collection of user's accesible albums
 * @property-read \Doctrine\Common\Collections\ArrayCollection $FavoritesAlbums Collection of user's favorites albums
 * @property-read \Doctrine\Common\Collections\ArrayCollection $FavoritesUsers Collection of user's favorites users
 *  
 * @entity
 * @table(name="tusers", indexes={@index(name="TUsers_TLanguages_FK", columns="Language"), 
 *                                @index(name="TUsers_TMimeTypes_FK", columns="AvatarMimeType"),
 *                                @index(name="TUsers_TStyles_FK", columns="Style")})
 *
 */     
class User {
  
  const PATH = 'images/tusers/';
  
  /**
   * Unique user ID
   * 
   * @access private
   * @var int
   *    
   * @Id 
   * @column(name="idUser", type="integer")
   * @generatedValue(strategy="IDENTITY") 
   */
   private $idUser;
     
  /**
   * Username is used to login into system.
   * 
   * @access private
   * @var string
   * 
   * @column(name="UserName", type="string", length=30, unique=true)
   */
   private $userName;
     
  /**
   * Password is used to login into system.
   * 
   * @access private
   * @var string
   * 
   * @column(name="Password", type="string", length=40)
   */
   private $password;
     
  /**
   * First Name of user. Can be null
   * 
   * @access private
   * @var string
   * 
   * @column(name="FirstName", type="string", length=30, nullable=true)
   */
   private $firstName;
     
  /**
   * Surname of user. Can be null
   * 
   * @access private
   * @var string
   * 
   * @column(name="LastName", type="string", length=30, nullable=true)
   */
   private $lastName;
   
   /**
    * @access private
    * @var string 
    * 
    * @column(name="Gender", type="string", length=10, nullable=true)
    */
   private $gender;
     
  /**
   * E-mail address
   * 
   * @access private
   * @var string
   * 
   * @column(name="EMail", type="string", length=30, unique=true)
   */
   private $eMail;
     
  /**
   * ICQ number. Can be null
   * 
   * @access private
   * @var string
   * 
   * @column(name="ICQ", type="string", length=10, nullable=true)
   */
   private $icq;
     
  /**
   * Jabber address. Can be null
   * 
   * @access private
   * @var string
   * 
   * @column(name="Jabber", type="string", length=30, nullable=true)
   */
   private $jabber;
   
   /**
    *
    * @access private
    * @var string
    * 
    * @column(name="WebPage", type="string", length=30, nullable=true)
    */
   private $webpage;
     
  /**
   * Binary image data. Can be null
   * 
   * @access private
   * @var string
   * 
   * @column(name="AvatarUNC", type="string", length="50", nullable=true)
   */
   private $avatarUNC;
     
  /**
   * Image width. Can be null
   * 
   * @access private
   * @var int
   * 
   * @column(name="AvatarWidth", type="integer", nullable=true)
   */
   private $avatarWidth;
     
  /**
   * Image height. Can be null
   * 
   * @access private
   * @var int
   * 
   * @column(name="AvatarHeight", type="integer", nullable=true)
   */
   private $avatarHeight;
     
  /**
   * Name of Mimetype of image. Can be null
   * 
   * @access private
   * @var string
   * 
   * @column(name="AvatarMimeType", type="string", length=50, nullable=true)
   */
   private $avatarMimeTypeName;
   
   /**
   * Mimetype of image. Can be null
   * 
   * @access private
   * @var MimeType
   * 
   * @manyToOne(targetEntity="MimeType")
   * @joinColumn(name="AvatarMimeType", referencedColumnName="Mime") 
   */
   private $avatarMimeType;
     
  /**
   * User's prefered language
   * 
   * @access private
   * @var string
   * 
   * @column(name="idLanguage", type="string", length=10)
   */
   private $languageName;
   
   /**
   * Name of user's prefered language
   * 
   * @access private
   * @var Language
   * 
   * @manyToOne(targetEntity="Language")
   * @joinColumn(name="idLanguage", referencedColumnName="idLanguage")
   */
   private $language;
     
   
  /**
   * Name of user's prefered style
   * 
   * @access private
   * @var string
   * 
   * @column(name="idStyle", type="string", length=30)
   */
   private $styleName;
   
  /**
   * User's prefered style
   * 
   * @access private
   * @var Style
   * 
   * @manyToOne(targetEntity="Style")
   * @joinColumn(name="idStyle", referencedColumnName="idStyle")
   */
   private $style;
   
   /**
    *
    * @access private
    * @var boolean 
    * 
    * @column(name="isActive", type="boolean")
    */
   private $isActive;
   
   /**
    *
    * @access private
    * @var boolean 
    * 
    * @column(name="isRecovery", type="boolean")
    */
   private $isRecovery;
   
   /**
    *
    * @access private
    * @var string
    * 
    * @column(name="Token", type="string", length=32)
    */
   private $token;
   
   /**
    *
    * @access private
    * @var DateTime 
    * 
    * @column(name="LastAction", type="datetimetz")
    */
   private $lastAction;
   
   /**
    *
    * @access private
    * @var DateTime 
    * 
    * @column(name="RegistrationDate", type="datetimetz")
    */
   private $registrationDate;
   
   /**
    * @access private
    * @var string 
    * 
    * @column(name="Details", type="string")
    */
   private $details;
   
   /**
    * Collection of user's albums
    * 
    * @access private
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * 
    * @oneToMany(targetEntity="Album", mappedBy="user")
    */
   private $albums;
   
   /**
    * Collection of user's comments
    * 
    * @access private
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * 
    * @oneToMany(targetEntity="Comment", mappedBy="user")
    * @OrderBy({"insertionDate" = "DESC"})
    */
   private $comments;
   
   /**
    * Collection of user's ratings
    * 
    * @access private
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * 
    * @oneToMany(targetEntity="Rating", mappedBy="user")
    */
   private $ratings;
   
   /**
    * Collection of user's notifications
    * 
    * @access private
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * 
    * @oneToMany(targetEntity="Notification", mappedBy="User")
    */
   private $notifications;
   
   /**
    *
    * @access private
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * 
    * @ManyToMany(targetEntity="Album", inversedBy="allowedUsers")
    * @JoinTable(name="taccess",
    *      joinColumns={@JoinColumn(name="idUser", referencedColumnName="idUser")},
    *      inverseJoinColumns={@JoinColumn(name="idAlbum", referencedColumnName="idAlbum")}
    *      )
    */
   private $accessible;
   
   /**
    *
    * @access private
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * 
    * @ManyToMany(targetEntity="Album", inversedBy="favoritesByUsers")
    * @JoinTable(name="tfavoritesalbums",
    *      joinColumns={@JoinColumn(name="id_User", referencedColumnName="idUser")},
    *      inverseJoinColumns={@JoinColumn(name="id_Album", referencedColumnName="idAlbum")}
    *      )
    */
   private $favoritesAlbums;
   
   /**
    *
    * @access private
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * 
    * @ManyToMany(targetEntity="User", inversedBy="favoritesWithMe")
    * @JoinTable(name="tfavoritesusers",
    *      joinColumns={@JoinColumn(name="idFavoriteUser", referencedColumnName="idUser")},
    *      inverseJoinColumns={@JoinColumn(name="idUser", referencedColumnName="idUser")}
    *      )
    */
   private $favoritesUsers;
   
   
   /**
    * @access private
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * 
    * @ManyToMany(targetEntity="User", mappedBy="favoritesUsers")
    */
   private $favoritesWithMe;
   
  public function __get($name) {
    
    switch($name) {
      
      case "idUser": 
        return $this->idUser;
        break;
     
      case "UserName": 
        return $this->userName;
        break;
     
      case "Password": 
        return $this->password;
        break;
     
      case "FirstName": 
        return $this->firstName;
        break;
      
      case "FullName": 
        return $this->firstName.' '.$this->lastName;
        break;
      
      case "Gender":
        return $this->gender;
        break;
     
      case "LastName": 
        return $this->lastName;
        break;
     
      case "EMail": 
        return $this->eMail;
        break;
     
      case "ICQ": 
        return $this->icq;
        break;
     
      case "Jabber": 
        return $this->jabber;
        break;
      
      case "WebPage": 
        return $this->webpage;
        break;
      
      case "AvatarUNC":
        return self::PATH.$this->avatarUNC;    
        //return ($this->avatarUNC === null) ? self::PATH.'nobody.png' : self::PATH.$this->avatarUNC;
        break;
     
      case "AvatarWidth": 
        return $this->avatarWidth;
        break;
     
      case "AvatarHeight": 
        return $this->avatarHeight;
        break;
     
      case "AvatarMimeType": 
        return $this->avatarMimeType;
        break;
      
      case "AvatarMimeTypeName": 
        return $this->avatarMimeTypeName;
        break;
      
      case "Language": 
        return $this->language;
        break;
      
      case "LanguageName": 
        return $this->languageName;
        break;
      
      case "Style": 
        return $this->style;
        break;
      
      case "StyleName": 
        return $this->styleName;
        break;
      
      case "Albums":
        return $this->albums;
        break;
      
      case "Comments":
        return $this->comments;
        break;
      
      case "Ratings":
        return $this->ratings;
        break;
      
      case "Notifications":
        return $this->notifications;
        break;
      
      case "AccessibleAlbums":
        return $this->accessible;
        break;
      
      case "FavoritesAlbums":
        return $this->favoritesAlbums;
        break;
        
      case "FavoritesUsers":
        return $this->favoritesUsers;
        break;
      
      case "isActive": 
        return $this->isActive;
        break;
      
      case "isRecovery": 
        return $this->isRecovery;
        break;
      
      case "Token":
        return $this->token;
        break;
      
      case "LastAction":
        return $this->lastAction;
        break;
      
      case "RegistrationDate":
        return $this->registrationDate;
        break;
      
      case "Details":
        return $this->details;
        break;
      
      default: 
        throw new EntityException(sprintf(T_("Trying to get undefined property")." ", $name));
    }
  }
  
  public function __set($name, $value) {
       
    switch($name) {

      case "UserName": 
        $this->userName = Validations::validateString($value, 30, Validations::regexp_UserName, false);
        break; 

      case "Password": 
        $this->password = Validations::validateString($value, 40, null, false);
        break; 

      case "FirstName": 
        $this->firstName = Validations::validateString($value, 30, null, true);
        break; 

      case "LastName": 
        $this->lastName = Validations::validateString($value, 30, null, true);
        break; 
      
      case "Gender":
        $this->gender = Validations::validateString(strtolower($value), 6, Validations::regexp_gender, true);
        break;

      case "EMail": 
        $this->eMail = Validations::validateString($value, 30, Validations::regexp_EMail, false);
        break; 

      case "ICQ": 
        $this->icq = Validations::validateString($value, 10, Validations::regexp_icq, true);
        break; 

      case "Jabber": 
        $this->jabber = Validations::validateString($value, 30, Validations::regexp_Jabber, true);
        break;
      
      case "WebPage": 
        $this->webpage = Validations::validateString($value, 60, Validations::regexp_url, true);
        break;

      case "AvatarUNC": 
        $position = strpos($value, self::PATH);
        if ($position !== false) {
          $value = str_replace(self::PATH, '', $value);
        }          
        $this->avatarUNC = Validations::validateString($value, 50, Validations::regexp_fileName, true);
        break; 

      case "AvatarWidth": 
        $this->avatarWidth = Validations::validateInteger($value, 0, null, true);
        break; 

      case "AvatarHeight": 
        $this->avatarHeight = Validations::validateInteger($value, 0, null, true);
        break; 

      case "AvatarMimeType": 
        $this->avatarMimeType = Validations::ValidateObject($value, 'MimeType');
        break; 
      
      case "AvatarMimeTypeName": 
        $this->avatarMimeType = Validations::validateString($value, 50, Validations::regexp_MimeType, true);
        break; 

      case "Language": 
        $this->language = Validations::ValidateObject($value, 'Language');;
        break; 

      case "LanguageName": 
        $this->languageName = Validations::validateString($value, 10, null, false);
        break;
      
      case "Style": 
        $this->style = Validations::ValidateObject($value, 'Style');
        break; 
      
      case "StyleName": 
        $this->styleName = Validations::validateString($value, 30, null, false);
        break;
      
      case "isActive": 
        $this->isActive = Validations::ValidateBoolean($value);
        break;
      
      case "isRecovery": 
        $this->isRecovery = Validations::ValidateBoolean($value);
        break;
      
      case "Token": 
        $this->token = Validations::validateString($value, 32, null, true);
        break;
      
      case "LastAction":
        $this->lastAction = Validations::ValidateObject($value, 'DateTime');
        break;
      
      case "Details":
        $this->details = Validations::validateString($value, null, null, true);
        break;      
      
      default: 
        throw new EntityException(sprintf(T_("Trying to set undefined property")." ", $name));
    }
  }  
  
  public static function genderToString($gender) {
    switch (strtolower($gender)) {
      case 'male':
        return T_('Male');
        break;
      case 'female':
        return T_('Female');
        break;
      default:
        return null;
    }
  }

    /**
   *
   * @access public
   * @param Album $album 
   * @return void
   */
  public function addAlbum(Album $album) {
    $this->albums->add($album);
    $album->User = $this;
  }
  
  /**
   *
   * @access public
   * @param Comment $comment 
   * @return void
   */
  public function addComment(Comment $comment) {
    $this->comments->add($comment);
    $comment->User = $this;
  }
  
  /**
   *
   * @access public
   * @param Rating $rating 
   * @return void
   */
  public function addRating(Rating $rating) {
    $this->ratings->add($rating);
    $rating->User = $this;
  }
  
  /**
   *
   * @access public
   * @param Notification $notification
   * @return void
   */
  public function addNotification(Notification $notification) {
    $this->notifications->add($notification);
    $notification->User = $this;
  }
  
  /**
   *
   * @access public
   * @param Album $album 
   * @return void
   */
  public function addAccessible (Album $album) {
    $this->accessible->add($album);
    //$album->addAllowedUser($this);
  }
  
  public function removeAccessible(Album $album) {
    $this->accessible->removeElement($album); 
    //$album->removeAllowedUser($this);
  }


  /**
   *
   * @access public
   * @param User $user 
   * @return void
   */
  public function addFavoriteUser(User $user) {
    $this->favoritesUsers->add($user);   
  }
  
  /**
   * @access public
   * @param User $user 
   * @return void
   */
  public function removeFavoriteUser(User $user) {
    $this->favoritesUsers->removeElement($user);
  }


 public function addFavoriteAlbum(Album $album) {
    $this->favoritesAlbums->add($album);
    $album->addFollower($this);
 }
  
  public function removeFavoriteAlbum(Album $album) {
    $this->favoritesAlbums->removeElement($album);
  }


    
  /**
   *
   * 
   */
  public function __construct() {
    $this->albums        = new \Doctrine\Common\Collections\ArrayCollection();
    $this->comments      = new \Doctrine\Common\Collections\ArrayCollection();
    $this->notifications = new \Doctrine\Common\Collections\ArrayCollection();
    $this->accessible    = new \Doctrine\Common\Collections\ArrayCollection();
    $this->favoritesAlbums = new \Doctrine\Common\Collections\ArrayCollection();
    $this->favoritesUsers = new \Doctrine\Common\Collections\ArrayCollection();
    $this->favoritesWithMe = new \Doctrine\Common\Collections\ArrayCollection();
    
    $this->registrationDate = new DateTime('now');
  }



}